package com.xx.robot.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.xx.robot.common.bean.CpHttpConfigBean;
import com.xx.robot.common.constant.CollectionNameEnum;
import com.xx.robot.common.constant.Jx3BoxUrlEnum;
import com.xx.robot.common.constant.TabsName;
import com.xx.robot.common.util.gocphttp.CqMessageUtil;
import com.xx.robot.common.util.mongo.MongoDbUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * jx3墨盒接口解析
 *
 * @author wiley
 */
@Service
@Slf4j
public class Jx3BoxService {

    /**
     * 定时爬取最新官网消息
     */
    public void news() {
        String result = HttpUtil.get(Jx3BoxUrlEnum.JX3BOX_WEBSITE_URL);
        if (!JSONUtil.isTypeJSON(result)) {
            log.error("api出问题了。。");
        }

        // 官网最新的一条
        JSONObject resultJson = JSONUtil.parseArray(result).getJSONObject(0);
        resultJson.set("datetime", DateUtil.now());

        // 补充url
        String url = resultJson.getStr("url");
        if (!url.startsWith(Jx3BoxUrlEnum.JX3_WEBSITE_URL)) {
            url = Jx3BoxUrlEnum.JX3_WEBSITE_URL + url;
            resultJson.set("url", url);
        }

        String cacheUrl;
        // 缓存的最新的一条news
        JSONObject latestNews = findSortDesc();
        if (JSONUtil.isNull(latestNews)) {
            // 缓存
            MongoDbUtil.save(resultJson, CollectionNameEnum.JX3_SERVE_NEWS.getCode());
            return;
        } else {
            cacheUrl = latestNews.getStr("url");
        }

        // 如果两个最新的url不相同则说明是最新的一条
        if (!CharSequenceUtil.equals(cacheUrl, url)) {
            // 缓存
            MongoDbUtil.save(resultJson, CollectionNameEnum.JX3_SERVE_NEWS.getCode());
            // 群发消息
            CqMessageUtil.groupSendAll(message(resultJson));
        }
    }

    /**
     * 发送最新消息
     *
     * @param groupId 群名
     */
    public void webNews(String groupId) {
        CqMessageUtil.groupSend(groupId, message(findSortDesc()));
    }


    /**
     * 拼接消息
     *
     * @param data json数据
     * @return 消息
     */
    private String message(JSONObject data) {
        return "江湖快报\n"
                + data.getStr("title") + "\n详情："
                + data.getStr("url") + "\n时间："
                + data.getStr("datetime");
    }

    private JSONObject findSortDesc() {
        // 缓存的最新的一条news
        Query query = new Query().with(Sort.by(Sort.Direction.DESC, "_id"));
        return MongoDbUtil.selectOneByQuery(query, JSONObject.class, CollectionNameEnum.JX3_SERVE_NEWS.getCode());
    }


    /**
     * 监控群已绑定服务器状态
     */
    public void statusMonitor() {
        // 获取已绑定服务器
        List<JSONObject> bindServerList = MongoDbUtil.selectAll(JSONObject.class, CollectionNameEnum.JX3_SERVER.getCode());
        bindServerList.forEach(o -> {
            String groupId = o.getStr("_id");
            String serverName = o.getStr("server");

            Boolean newStatus = findServerStatus(serverName);
            Boolean cacheStatus = o.getBool("server_status");

            boolean isChanged = false;
            // 关服提醒(新状态为关闭,与缓存状态不一致)
            if (Boolean.FALSE.equals(newStatus) && Boolean.TRUE.equals(cacheStatus)) {
                CqMessageUtil.groupSend(groupId, "gww带着小姨子停服跑路啦!" + serverName + "+【1比1314】挥泪收金，也可更换锅碗瓢盆！");
                isChanged = true;
                log.info("{}:关服了", serverName);
            }
            // 开服提醒(新状态为开启,与缓存状态不一致)
            if (Boolean.TRUE.equals(newStatus) && Boolean.FALSE.equals(cacheStatus)) {
                CqMessageUtil.groupSend(groupId, "开服啦开服啦！" + serverName + "服务器【1比520】浪漫出金！快上线交易吧！");
                isChanged = true;
                log.info("{}:开服了", serverName);
            }

            if (isChanged) {
                Query query = new Query(Criteria.where("_id").is(groupId));
                Update update = new Update().set("server_status", newStatus);
                MongoDbUtil.updateFirst(query, update, CollectionNameEnum.JX3_SERVER.getCode());
            }
        });

    }


    /**
     * 实时查询服务器状态
     *
     * @param groupId    群名
     * @param serverName 服务器器名
     */
    public void serverStatus(String groupId, String serverName) {
        boolean serverStatus = findServerStatus(serverName);
        if (ObjectUtil.isNull(serverStatus)) {
            CqMessageUtil.groupSend(groupId, "啊哦,服务好像崩了");
        }

        String str = "区服：" + serverName + "\n" +
                "状态：" + (serverStatus ? "开服啦开服啦！" + serverName + "【1比520】浪漫出金！快上线交易吧！" : "gww带着小姨子停服跑路啦!" + serverName + "+【1比1314】挥泪收金，也可更换锅碗瓢盆！");
        CqMessageUtil.groupSend(groupId, str);
    }


    /**
     * 获取服务器状态
     *
     * @param serverName 服务器名称
     * @return 服务器状态
     */
    public Boolean findServerStatus(String serverName) {
        String result = HttpUtil.get(Jx3BoxUrlEnum.JX3BOX_SERVER_URL);

        if (!JSONUtil.isTypeJSON(result)) {
            log.error("api出问题了。。");
        }

        JSONObject resultJson = JSONUtil.parseObj(result);

        List<JSONObject> serverStatusList = resultJson.getBeanList("data", JSONObject.class);
        // 查看状态
        return serverStatusList.stream()
                .filter(o -> CharSequenceUtil.equals(o.getStr("serverName"), serverName))
                .map(p -> p.getBool("connectState"))
                .findFirst().orElse(false);

    }

    /**
     * 奇遇攻略
     *
     * @param groupId 群名
     * @param message 消息
     */
    public void findQiYu(String groupId, String message) {
        message = CharSequenceUtil.replace(message, "奇遇", CharSequenceUtil.EMPTY).trim();

        // 查询有无此奇遇
        Map<String, Object> qiyuParamMap = new HashMap<>();
        qiyuParamMap.put("name", message);
        String result = HttpUtil.get(Jx3BoxUrlEnum.ADVENTURE_URL, qiyuParamMap, 30000);
        if (!JSONUtil.isTypeJSON(result)) {
            CqMessageUtil.groupSend(groupId, "api出问题了。。");
            return;
        }
        JSONObject resultJson = JSONUtil.parseObj(result);
        JSONArray list = resultJson.getJSONArray("list");
        if (CollUtil.isEmpty(list)) {
            CqMessageUtil.groupSend(groupId, "谁出奇遇了？什么奇遇!!");
        }
        // 获取 dwId
        String dwId = list.getJSONObject(0).getStr("dwID");

        // 永远执行
        if (true) {
            String url = Jx3BoxUrlEnum.ADVENTURE_PATH + "/" + dwId;
            String stringBuilder = "奇遇：" + message + "\n"
                    + "攻略：" + url;
            CqMessageUtil.groupSend(groupId, stringBuilder);
            return;
        }

        // ---------------------自己解析---------------------------------
        String dwIdData = HttpUtil.get("https://icon.jx3box.com/pvx/serendipity/output/serendipity.json", 3000);
        if (!JSONUtil.isTypeJSON(dwIdData)) {
            CqMessageUtil.groupSend(groupId, "api出问题了。。");
        }
        Integer sourceId = JSONUtil.parseObj(dwIdData).getInt(dwId);

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("type", "achievement");
        paramMap.put("source_id", sourceId);
        String resultData = HttpUtil.get("https://helper.jx3box.com/api/wiki/post", paramMap, 30000);
        if (!JSONUtil.isTypeJSON(resultData)) {
            CqMessageUtil.groupSend(groupId, "api出问题了。。");
        }
        JSONObject resultJsons = JSONUtil.parseObj(resultData);
        String code = resultJsons.getStr("code");
        if (!CharSequenceUtil.equals(code, "200")) {
            CqMessageUtil.groupSend(groupId, "api出问题了。。");
        }
        JSONObject postData = resultJsons.getJSONObject("data").getJSONObject("post");
        String content = postData.getStr("content");

        // 解析
        String savehtml = content;
        if (content.contains("<p>&nbsp;</p>")) {
            String[] split = content.split("<p>&nbsp;</p>");
            savehtml = split[1];
        }
        if (content.contains("<hr>")) {
            String[] split = content.split("<hr>");
            savehtml = split[1];
        }
        // 缓存
        HashMap<String, Object> map1 = new HashMap<>();
        map1.put("_id", postData.get("title"));
        map1.put("content", savehtml);
        MongoDbUtil.save(map1, CollectionNameEnum.JX3_ACHIEVEMENT_STRATEGY.getCode());

        // 发送消息
    }

    /**
     * 宏 查询
     *
     * @param groupId
     * @param message
     */
    public void macro(String groupId, String message) {
        message = CharSequenceUtil.replace(message, "宏", CharSequenceUtil.EMPTY).trim();

        HashMap<String, Object> paramMap = new HashMap<>(8);
        paramMap.put("type", "macro");
        paramMap.put("per", "10");
        paramMap.put("page", "1");
        paramMap.put("subtype", URLUtil.decode(message));
        paramMap.put("order", "update");
        paramMap.put("client", "std");
        paramMap.put("sticky", "1");

        String result = HttpUtil.get("https://cms.jx3box.com/api/cms/posts", paramMap);

        JSONObject resultJson = JSONUtil.parseObj(result);
        Integer code = resultJson.getInt("code");
        if (code == 0) {
            JSONObject data = resultJson.getJSONObject("data").getJSONArray("list").getJSONObject(0);

            StringBuilder str = new StringBuilder();
            JSONArray macroList = data.getJSONObject("post_meta").getJSONArray("data");

            // 最多查询3条
            int len = Math.min(macroList.size(), 3);
            for (int i = 0; i < len; i++) {
                JSONObject o = macroList.getJSONObject(i);
                str.append("宏名称：").append(o.getStr("name")).append("\n");
                str.append("备注：【").append(o.getStr("desc")).append("】\n");
                str.append(o.getStr("macro")).append("\n\n");
            }
            CqMessageUtil.groupSend(groupId, str.toString());
        }
    }

    /**
     * 宏查询(j3box),最近7天使用最多
     *
     * @param groupId 群号
     * @param message 消息
     */
    public void macroRank(String groupId, String message) {
        message = CharSequenceUtil.replace(message, "宏", CharSequenceUtil.EMPTY).trim();

        /**
            1
         */
        // 如果是数字，直接当作uid处理
        // 否则，先去查询是否为门派别称，然后通过门派获取
        // 然后在从mongo从看是否为统计中的别称

        if (NumberUtil.isNumber(message)) {
            macroJ3BoxUId(groupId, message);
            return;
        }

        // 获取职业
        String subtype = TabsName.hongMap.get(message);
        if (CharSequenceUtil.isNotBlank(subtype)) {
            microJ3BoxSubtype(groupId, subtype);
            return;
        }

        JSONObject box = MongoDbUtil.selectById(message, JSONObject.class, CollectionNameEnum.JX3_BOX_UID.getCode());
        if (!JSONUtil.isNull(box)) {
            macroJ3BoxUId(groupId, box.getStr("box_uid"));
        }

    }

    /**
     * 根据职业查宏
     *
     * @param groupId 群名
     * @param subtype 职业名
     */
    private void microJ3BoxSubtype(String groupId, String subtype) {
        HashMap<String, Object> paramMap = new HashMap<>(8);
        paramMap.put("kungfu", TabsName.BOX_SUB_TYPE.get(subtype));
        paramMap.put("size", "1");
        paramMap.put("client", "std");
        String result = HttpUtil.get("https://next2.jx3box.com/api/macro/tops", paramMap);
        String pid = JSONUtil.parseArray(result).getJSONObject(0).getStr("pid");
        log.info(pid);

        String micro = HttpUtil.get("https://cms.jx3box.com/api/cms/post/" + pid);
        log.info(micro);
        JSONObject microJson = JSONUtil.parseObj(micro);

        JSONObject data = microJson.getJSONObject("data");
        String author = data.getStr("author");

        StringBuilder str = new StringBuilder();
        JSONArray macroList = data.getJSONObject("post_meta").getJSONArray("data");

        // 最多查询3条
        str.append("默认获取最近7天内使用次数最多的宏：").append("\n\n");
        for (int i = 0; i < macroList.size(); i++) {
            JSONObject o = macroList.getJSONObject(i);
            str.append("云端宏名称：【").append(author).append("#").append(o.getStr("name")).append("】\n");
            str.append("宏作者小贴士：【").append(o.getStr("desc")).append("】\n");
            str.append("--------------------------------\n");
            str.append(o.getStr("macro")).append("\n\n");
            str.append("奇穴：【").append(o.getStr("talent")).append("】\n");
            str.append("--------------------------------\n");
        }
        CqMessageUtil.groupSend(groupId, str.toString());
    }


    /**
     * 查询jxBox宏
     *
     * @param groupId 群号
     */
    private void macroJ3BoxUId(String groupId, String boxUserId) {
        String result = HttpUtil.get("https://cms.jx3box.com/api/cms/posts/user/" + boxUserId + "/latest");
        JSONArray list = JSONUtil.parseObj(result).getJSONObject("data").getJSONArray("list");
        if (CollUtil.isEmpty(list)) {
            CqMessageUtil.groupSend(groupId, "无此userId,请确认后在试");
        }

        var str = new StringBuilder();
        list.stream().map(o -> (JSONObject) o).forEach(aciJson -> {
            String postTitle = aciJson.getStr("post_title");
            JSONArray macroList = aciJson.getJSONObject("post_meta").getJSONArray("data");
            for (Object p : macroList) {
                JSONObject macroJson = (JSONObject) p;
                str.append("职业：").append(postTitle).append("---").append(macroJson.getStr("name")).append("\n");
                str.append(macroJson.getStr("macro")).append("\n\n");
            }
        });
        CqMessageUtil.groupSend(groupId, str.toString());
    }

    /**
     * 时间排序
     *
     * @param subtype 心法
     * @return
     */
    public String microUpdateMessage(String subtype) {
        HashMap<String, Object> paramMap = new HashMap<>(8);
        paramMap.put("type", "macro");
        paramMap.put("per", "10");
        paramMap.put("page", "1");
        paramMap.put("subtype", URLUtil.decode(subtype));
        paramMap.put("order", "update");
        paramMap.put("client", "std");
        paramMap.put("sticky", "1");

        return HttpUtil.get("https://cms.jx3box.com/api/cms/posts", paramMap);
    }


    /**
     * 查询奇遇。
     *
     * @param name 奇遇名称
     * @return
     */
    public String findqiyu(String name) {
        Query query = new Query(Criteria.where("_id").is(name));
        List<JSONObject> data = MongoDbUtil.selectByQuery(query, JSONObject.class, CollectionNameEnum.JX3_ACHIEVEMENT_STRATEGY.getCode());
        if (CollUtil.isEmpty(data)) {
            return "唉！" + CpHttpConfigBean.ROBOT_NAME + "查询出错了欸！快打我两巴掌。";
        }
        return data.get(0).getStr("content");
    }
}
